﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
using System.Text;

namespace Rose.Helper
{
    public class WormShareContentHelpModel
    {
        public  bool IsLinkUseless
        {
            get;
            set;
        }


        public string AnalyseLink(string url)
        { 
             string source = GetUft8Html(url);
            List<string> model = GetTagList(source, "meta");

            bool isutf8 = IsUtf8(model);
            if (isutf8)
            {
                //title first
                return GetDescriptionContentOrTitle(model,true);
            }
            else
            {
                string newsource = GetGbkHtml(url);
                List<string> newmodel = GetTagList(newsource,"meta");
                return GetDescriptionContentOrTitle(newmodel,true);

            }
           

        }



      

        #region  内部辅助方法;

        private string GetDescriptionContentOrTitle(List<string> model,bool isTitleFirst)
        {
            
            if (isTitleFirst)
            {
                List<string> returnModel = GetTitleList(model);
                if (returnModel.Count > 0)
                    foreach (string n in returnModel)
                    {
                        return GetTitle(n);

                    }
                else
                {

                    foreach (string n in GetDescriptionList(model))
                    {
                        return GetDescriptionContent(n);
                    }
                }
            }
            else
            {
                List<string> returnModel = GetDescriptionList(model);
                if (returnModel.Count > 0)
                    foreach (string n in returnModel)
                    {
                        return GetDescriptionContent(n);

                    }
                else
                {

                    foreach (string n in GetTitleList(model))
                    {
                        return GetTitle(n);
                    }
                }
            }
           
            return string.Empty;
        }



        string GetDescriptionContent(string source)
        {
            source = source + "\"";
            Regex regex_begin = new Regex("content=", RegexOptions.IgnoreCase);

            Regex regex_begin_end = new Regex("\"", RegexOptions.IgnoreCase);

            Regex regex_end = new Regex(">", RegexOptions.IgnoreCase);

            MatchCollection begin_matches = regex_begin.Matches(source);
            if (begin_matches.Count <= 0)
                return string.Empty;


            int beginindex = begin_matches[0].Index;

            string tempstring = source.Substring(beginindex);
            MatchCollection endmatch = regex_begin_end.Matches(tempstring);


            if (endmatch.Count <= 1)
                return string.Empty;


            beginindex = endmatch[0].Index + 1;
            int length = endmatch[1].Index - beginindex;
            string returnstring = tempstring.Substring(beginindex, length);
            return returnstring;

        }


        string GetTitle(string source)
       {
           Regex regex_title = new Regex("<\\s*title" + "[^>]*");
           Regex regex_title_end = new Regex("</\\s*title\\s*>");
           MatchCollection regex_titlematches = regex_title.Matches(source);

           if (regex_titlematches.Count <= 0)
               return string.Empty;
           source = source.Substring(regex_titlematches[0].Index);
           //
           Regex regex_back = new Regex(">");
           MatchCollection regex_backmatches = regex_back.Matches(source);

           MatchCollection regex_endmatches = regex_title_end.Matches(source);
           if (regex_endmatches.Count <= 0 || regex_backmatches.Count <= 0)
               return string.Empty;
           int begin = regex_backmatches[0].Index + 1;
           int length = regex_endmatches[0].Index - begin;

           return source.Substring(begin, length);

       }


        bool IsUtf8(List<string> source)
       {

           foreach (string item in source)
           {
               Regex regex_charset = new Regex("charset=\"?utf-?8\"?", RegexOptions.IgnoreCase);
               if (regex_charset.Matches(item).Count > 0)
                   return true;
           }
           return false;
       }

        string ChangeCharToString(char[] chardata)
       {
           return new string(chardata);

       }


        List<string> GetChinese(string source)
       {
           List<string> returnModel = new List<string>();
           Regex regex_chinese = new Regex("[\u4e00-\u9fa5]*");
           MatchCollection matches = regex_chinese.Matches(source);
           foreach (Match match in matches)
           {
               string add = match.Value;
               if (!string.IsNullOrEmpty(add))
                   returnModel.Add(add);
           }
           return returnModel;

       }

        List<string> GetDescriptionList(List<string> source)
       {
           List<string> returnModel = new List<string>();
           foreach (string item in source)
           {
               Regex regex_description = new Regex("description", RegexOptions.IgnoreCase);
               if (regex_description.Matches(item).Count > 0)
                   returnModel.Add(item);
           }
           return returnModel;
       }



        List<string> GetKeyWordList(List<string> source)
       {
           List<string> returnModel = new List<string>();
           foreach (string item in source)
           {

               Regex regex_keyword = new Regex("keyword", RegexOptions.IgnoreCase);

               if (regex_keyword.Matches(item).Count > 0)
                   returnModel.Add(item);
           }
           return returnModel;
       }

        List<string> GetTitleList(List<string> source)
       {
           List<string> returnModel = new List<string>();
           foreach (string item in source)
           {
               Regex regex_title = new Regex("<title>", RegexOptions.IgnoreCase);

               if (regex_title.Matches(item).Count > 0)
                   returnModel.Add(item);
           }
           return returnModel;
       }

        List<string> GetKeyWordDescriptionTitleList(List<string> source)
       {
           List<string> returnModel = new List<string>();
           foreach (string item in source)
           {
               Regex regex_title = new Regex("<title>", RegexOptions.IgnoreCase);
               Regex regex_keyword = new Regex("keyword", RegexOptions.IgnoreCase);
               Regex regex_description = new Regex("description", RegexOptions.IgnoreCase);
               if (regex_description.Matches(item).Count > 0 || regex_title.Matches(item).Count > 0 || regex_keyword.Matches(item).Count > 0)
                   returnModel.Add(item);
           }
           return returnModel;
       }

        string GetGbkHtml(string url)
       {
           try
           {
               WebClient client = new WebClient();
               byte[] bytedata = client.DownloadData(url);
               char[] chardata = new char[bytedata.Length];
               Encoding.Default.GetChars(bytedata, 0, bytedata.Length, chardata, 0);
               IsLinkUseless = false;
               return ChangeCharToString(chardata);
           }
           catch
           {
               IsLinkUseless = true;
               return string.Empty;
           }
       }

       public  string GetUft8Html(string url)
       {
           WebClient client = new WebClient();
           byte[] bytedata = client.DownloadData(url);
           char[] chardata = new char[bytedata.Length];
           Encoding.UTF8.GetChars(bytedata, 0, bytedata.Length, chardata, 0);

           return ChangeCharToString(chardata);

       }

       //static string ChangeUtf8ToGbk(string source)
       //{
       //    char[] chardata = source.ToCharArray();
       //    byte[] bytedata = new byte[chardata.Length*8];
       //    Encoding.Default.GetBytes(chardata, 0, chardata.Length, bytedata, 0);
       //    char[] newchar = new char[bytedata.Length];
       //    Encoding.UTF8.GetChars(bytedata, 0, bytedata.Length,newchar, 0);


       //    return new string(newchar);
       //}

        List<string> GetTagList(string source, string tag = "meta", string title = "title")
       {
           List<string> returnModel = new List<string>();
           if (string.IsNullOrEmpty(source))
               return returnModel;

           //string begin = "<\\s*" + tag +".*";
           string begin = "<" + tag + "[^>]*" + ">";
           string head = "</head>";
           //to protect the error match ,so the last is the head
           string tempsource = string.Empty;
           int count = 0;
           int headcount = 0;
           Regex regex_begin = new Regex(begin, RegexOptions.IgnoreCase);
           Regex regex_head = new Regex(head, RegexOptions.IgnoreCase);

           MatchCollection match_begin = regex_begin.Matches(source);
           MatchCollection match_head = regex_head.Matches(source);

           if ((headcount = match_head.Count) <= 0)
               return returnModel;

           int headindex = match_head[0].Index;
           source = source.Substring(0, headindex);


           if (!string.IsNullOrEmpty(title))
           {


               Regex regex_title = new Regex("<\\s*title" + "[^>]*");
               Regex regex_end = new Regex("</\\s*title\\s*>");
               MatchCollection regex_titlematches = regex_title.Matches(source);
               MatchCollection regex_endmatches = regex_end.Matches(source);
               if (regex_titlematches.Count > 0 && regex_endmatches.Count > 0)
               {
                   int length = regex_endmatches[0].Index + regex_endmatches[0].Value.Length - regex_titlematches[0].Index;
                   returnModel.Add(source.Substring(regex_titlematches[0].Index, length));

               }


           }

           if ((count = match_begin.Count) <= 0)
           {

               return returnModel;

           }



           for (int i = 0; i < count; i++)
           {
               tempsource = source.Substring(match_begin[i].Index, match_begin[i].Value.Length);
               returnModel.Add(tempsource);
           }


           return returnModel;



       }

        #endregion

    }
}